/**
 * @file geminai_mqtt_cache.c
 * @brief 队列上传信息到阿里云
 * @author zl
 */
#include "geminai_mqtt_cache.h"
#include "geminai_frig.h"
#include "geminai_modbus.h"
#include "geminai_log.h"
#include "remote_shell.h"
#include "geminai_audio.h"

#define TAG "MQTT_CACHE"
void *shadow_handler;
void *dm_handler;
QueueHandle_t mqtt_queue;
static uint16_t report_interval;
static uint16_t shadow_version;

/**
 * @brief 定义key值
 */
const char *temperature_difference      = "temperature_difference";      ///< 温控器回差温度
const char *temperature_target          = "temperature_target";          ///< 温控器目标温度
const char *volume                      = "volume";                      ///< 嗽叭音量值大小
const char *evaporator_status           = "evaporator_status";           ///< 蒸发风机开启关闭状态
const char *time_zone                   = "timezone";                    ///< 设备系统时区
const char *compressor_min_downtime     = "compressor_min_downtime";     ///< 压缩机最小停机时间
const char *temperature_max_threshold   = "temperature_max_threshold";   ///< 温控器高温报警值
const char *temperature_min_threshold   = "temperature_min_threshold";   ///< 温控器低温报警值
const char *asset_id                    = "asset_id";                    ///< 资产编码
const char *light_switch_status         = "light_switch_status";         ///< 灯开关状态
const char *colding_switch_status       = "colding_switch_status";       ///< 制冷开关状态
const char *colding_status              = "colding_status";              ///< 制冷状态


/* 发送更新设备影子reported值的请求 */
int32_t demo_update_shadow(void *shadow_handle, char *reported_data, int64_t version)
{
    aiot_shadow_msg_t message;

    memset(&message, 0, sizeof(aiot_shadow_msg_t));
    message.type = AIOT_SHADOWMSG_UPDATE;
    message.data.update.reported = reported_data;
    message.data.update.version = version;

    return aiot_shadow_send(shadow_handle, &message);
}

/* 发送删除设备影子中特定reported值的请求 */
int32_t demo_delete_shadow_report(void *shadow_handle, char *reported, int64_t version)
{
    aiot_shadow_msg_t message;

    memset(&message, 0, sizeof(aiot_shadow_msg_t));
    message.type = AIOT_SHADOWMSG_DELETE_REPORTED;
    message.data.delete_reporte.reported = reported;
    message.data.delete_reporte.version = version;

    return aiot_shadow_send(shadow_handle, &message);
}

/* 发送清除设备影子中所有desired值的请求 */
int32_t demo_clean_shadow_desired(void *shadow_handle, int64_t version)
{
    aiot_shadow_msg_t message;

    memset(&message, 0, sizeof(aiot_shadow_msg_t));
    message.type = AIOT_SHADOWMSG_CLEAN_DESIRED;
    message.data.clean_desired.version = version;

    return aiot_shadow_send(shadow_handle, &message);
}

/* 发送获取设备影子的请求 */
int32_t demo_get_shadow(void *shadow_handle)
{
    aiot_shadow_msg_t message;

    memset(&message, 0, sizeof(aiot_shadow_msg_t));
    message.type = AIOT_SHADOWMSG_GET;

    return aiot_shadow_send(shadow_handle, &message);
}

void print_partial_string(const char *str, int n) {
    for (int i = 0; i < n ; i++) {
        putchar(str[i]);
    }
    putchar('\n');
}

/* shadow 数据处理回调, 当SDK从网络上收到shadow消息时被调用 */
void demo_shadow_recv_handler(void *handle, const aiot_shadow_recv_t *recv, void *userdata)
{
    printf("demo_shadow_recv_handler, type = %d, productKey = %s, deviceName = %s\r\n",
           recv->type, recv->product_key, recv->device_name);

    switch (recv->type) {
        /* 当设备发送AIOT_SHADOWMSG_UPDATE, AIOT_SHADOWMSG_CLEAN_DESIRED或者AIOT_SHADOWMSG_DELETE_REPORTED消息后, 会收到此应答消息 */
        case AIOT_SHADOWRECV_GENERIC_REPLY: {
            const aiot_shadow_recv_generic_reply_t *generic_reply = &recv->data.generic_reply;

            print_partial_string(generic_reply->payload, generic_reply->payload_len);
            printf("status = %s, timestamp = %ld\r\n",
                   generic_reply->status,
                   (unsigned long)generic_reply->timestamp);
        }
        break;
        /* 当设备在线时, 若用户应用程序调用云端API主动更新设备影子, 设备便会收到此消息 */
        case AIOT_SHADOWRECV_CONTROL :
        /* 当设备发送AIOT_SHADOWMSG_GET消息主动获取设备影子时, 会收到此消息 */
        case AIOT_SHADOWRECV_GET_REPLY: 
            const aiot_shadow_recv_get_reply_t *get_reply = &recv->data.get_reply;

            // print_partial_string(get_reply->payload, get_reply->payload_len);
            printf(" version = %ld\r\n",
                   (unsigned long)get_reply->version);
            shadow_version = get_reply->version;       

            cJSON *root = cJSON_ParseWithLength(get_reply->payload, get_reply->payload_len);
            cJSON *state, *desired, *frig, *para, *system;
            state = cJSON_GetObjectItem(root, "state");
            if (state != NULL)
            {
                desired = cJSON_GetObjectItem(state, "desired");
                if (desired != NULL)
                {
                        frig = cJSON_GetObjectItem(desired, "frig");
                        if (frig != NULL)
                        {
                            para = cJSON_GetObjectItem(frig, "overtemp_alert");            if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.overtemp = para->valueint;}}
                            para = cJSON_GetObjectItem(frig, "defrost_shielding_time");    if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.defrost_shielding_time = para->valueint;}}
                            para = cJSON_GetObjectItem(frig, "defrost_time");              if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.defrost_time = para->valueint;}}
                            para = cJSON_GetObjectItem(frig, "lowtemp_alert");             if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.lowtemp = para->valueint;}}
                            para = cJSON_GetObjectItem(frig, "overtemp_alarm_delay_time"); if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.overtemp_alarm_delay_time = para->valueint;}}
                            para = cJSON_GetObjectItem(frig, "start_shielding_time");      if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.start_shielding_time = para->valueint;}}
                            para = cJSON_GetObjectItem(frig, "defrost_cycle");             if(para != NULL){if (cJSON_IsNumber(para)) {temp_ctl_para.defrost_cycle = para->valueint;}}
                        }
                        system = cJSON_GetObjectItem(desired, "system");
                        if (system != NULL)
                        {
                            para = cJSON_GetObjectItem(system, "report_interval");         if(para != NULL){if (cJSON_IsNumber(para)) {report_interval = para->valueint;}}
                            para = cJSON_GetObjectItem(system, "volume");                  if(para != NULL){if (cJSON_IsNumber(para)) {system_para.volume = para->valueint;}}
                        }                        
                    
                }
            }            
            attribute_send_event |= PARA_SHADOW;

            break;
        default:
            break;
    }
}

//物理型回调函数
void yqsl_np_dm_recv_handler(void *handle, const aiot_dm_recv_t *recv, void *userdata)
{
    /*填充接收到的数据处理逻辑*/
    printf("product_key: %s device_name:%s\n", recv->product_key, recv->device_name);
    printf("yqsl_np_dm_recv_handler type:%d\n", recv->type);
    
    if(recv->type == AIOT_DMRECV_PROPERTY_SET)//属性设置
    {
        cJSON *para;
        printf("msgid = %lld\n",recv->data.property_set.msg_id);
        printf("msg = %ld\n",recv->data.property_set.params_len);
        printf("*********\n");
        for(int i=0 ; i<recv->data.property_set.params_len ; i++)
        {
            printf("%c",recv->data.property_set.params[i]);
        }
        printf("\n**********\n");

        // cJSON *root = cJSON_Parse(recv->data.property_set.params);/*使用这个解析会导致解析错误，服务器下发的并不是\0结尾的字符串*/
        cJSON *root = cJSON_ParseWithLength(recv->data.property_set.params, recv->data.property_set.params_len);
        if (root == NULL) {
            printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
            return;
        }

        para = cJSON_GetObjectItem(root, "temperature_difference");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                temp_ctl_para.temp_diff = para->valueint;
                attribute_send_event |= PARA_SET_TEMP_DIFF;
                printf("temperature_difference: %d\n", para->valueint);
            }
        }

        para = cJSON_GetObjectItem(root, "temperature_target");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                temp_ctl_para.temp_des = para->valueint;
                attribute_send_event |= PARA_SET_TEMP_DES;
                printf("temperature_target: %d\n", para->valueint);
            }
        }

        para = cJSON_GetObjectItem(root, "compressor_min_downtime");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                temp_ctl_para.delay_tim = para->valueint;
                attribute_send_event |= PARA_SET_DELAY_TIM;
                printf("compressor_min_downtime: %d\n", para->valueint);
            }
        }

        para = cJSON_GetObjectItem(root, "light_switch_status");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                led_status = para->valueint;
                attribute_send_event |= PARA_LIGHT_SWITCH;
                printf("light_switch_status: %d\n", para->valueint);
            }
        }

        para = cJSON_GetObjectItem(root, "colding_switch_status");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                frig_sys_switch = para->valueint;
                attribute_send_event |= PARA_COOL_SWITCH;
                printf("colding_switch_status: %d\n", para->valueint);
            }
        }

        para = cJSON_GetObjectItem(root, "logo_light_status");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                led_status = para->valueint;
                attribute_send_event |= PARA_LIGHT_SWITCH;
            }
        }   

        para = cJSON_GetObjectItem(root, "logo_light_brightness");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                temp_ctl_para.led_pwm = para->valueint;
                attribute_send_event |= PARA_LED_PWM;
            }
        }           

        para = cJSON_GetObjectItem(root, "kn_fridge_config:colding_status");
        if (para != NULL) {
            if (cJSON_IsNumber(para)) {
                uint8_t frig_stat= para->valueint;
                do
                {
                    if(frig_stat != 3 && aiot_get_frig_stat() == 3)
                    {
                        if(overtemp_time < temp_ctl_para.defrost_shielding_time)       //除霜后屏蔽时间
                        {
                            overtemp_time = temp_ctl_para.defrost_shielding_time;
                        }
                    }
                    if(frig_stat == 2)
                    {
                        temp_ctl_para.forced_cooling = 0;
                        frig_event_set(EVENT_FRIG_NORMAL_STATE);//发送正常制冷模式事件
                        alarm_stat &=~ ALARM_DEFORST;                                                  //取消df除霜
                        alarm_stat &=~ ALARM_FORCED_COOL;                                      //取消CC强制制冷
                        frig_set_stat(frig_stat,temp_ctl_para.delay_tim*60);
                    }
                    else
                    {
                        if(((sys_temp.temp_per_min < TEMP_ERR_LOWER) || (sys_temp.temp_per_min > TEMP_ERR_UPPER)) && frig_stat == FRIG_STAT_FORCE_MODE)
                            break;
                        frig_set_stat(frig_stat,0);
                    }
                    printf("colding_status: %d\n", para->valueint);
                }while(0);
            }
        }
    }
    if(recv->type == AIOT_DMRECV_SYNC_SERVICE_INVOKE) 
    { // 同步服务调用
        cJSON *root = cJSON_ParseWithLength(recv->data.sync_service_invoke.params, recv->data.sync_service_invoke.params_len);
        print_partial_string(recv->data.sync_service_invoke.params, recv->data.sync_service_invoke.params_len);
        if (root == NULL) 
        {
            printf("cJSON_Parse error\n");
            return;
        }
        if (strcmp(recv->data.sync_service_invoke.service_id, "operation_instruction") == 0) 
        {
            cJSON *command = cJSON_GetObjectItem(root, "command");
            cJSON *args = cJSON_GetObjectItem(root, "args");
            if (command != NULL && args != NULL) 
            {
                cJSON *args_json = cJSON_Parse(args->valuestring);
                if (args_json != NULL) {
                    cJSON *delay = cJSON_GetObjectItem(args_json, "delay");
                    cJSON *timestamp = cJSON_GetObjectItem(args_json, "timestamp");
                    if (delay != NULL && timestamp != NULL) 
                    {
                        reboot_arg.delay = delay->valueint;
                        reboot_arg.timestamp = timestamp->valueint;
                        Task task = {reboot_cmd, (void*)&reboot_arg};
                        enqueue(&mb_task_queue, task);
                    }
                    cJSON_Delete(args_json);
                }
            }
        } else if (strcmp(recv->data.sync_service_invoke.service_id, "frp_link") == 0) {
            cJSON *frp_ip = cJSON_GetObjectItem(root, "frp_ip");
            cJSON *listen_port = cJSON_GetObjectItem(root, "listen_port");
            cJSON *comm_port = cJSON_GetObjectItem(root, "comm_port");
            if (frp_ip != NULL && listen_port != NULL && comm_port != NULL) {
                frp_arg.frp_ip = strdup(frp_ip->valuestring);
                frp_arg.listen_port = listen_port->valueint;
                frp_arg.comm_port = comm_port->valueint;
                if (frp_arg.listen_port != frp_arg.comm_port) { 
                    Task task = {frp, (void*)&frp_arg};
                    enqueue(&mb_task_queue, task);
                } else {
                    Task task = {remote_shell, (void*)&frp_arg};
                    enqueue(&mb_task_queue, task);
                }
            }
        }
        else if (strcmp(recv->data.sync_service_invoke.service_id, "set_configuration") == 0) {
            cJSON *configuration = cJSON_GetObjectItem(root, "configuration");
            if (configuration != NULL ) 
            {
                printf("configuration: %s\n", configuration->valuestring);
                if(strcmp(configuration->valuestring, "{\"file\": [{\"name\": \"\",\"data\": \"\",\"version\": \"1648459171888\"}],\"operation\": \"cp -rf /userdata/ > /dev/null;mplayer -af volume=100 /oem/aisha/sounds/err_cpu_test_ok.mp3\"}") == 0)
                {
                    app_play_wav(1, "/spiffs/err_cpu_test_ok.wav");
                    char *serviceId = malloc(strlen(recv->data.sync_service_invoke.service_id) + 1);
                    memset(serviceId, 0, strlen(recv->data.sync_service_invoke.service_id) + 1);
                    strcpy(serviceId, recv->data.sync_service_invoke.service_id);
                    char *rrpc_id = malloc(strlen(recv->data.sync_service_invoke.rrpc_id) + 1);
                    memset(rrpc_id, 0, strlen(recv->data.sync_service_invoke.rrpc_id) + 1);
                    strcpy(rrpc_id, recv->data.sync_service_invoke.rrpc_id);
                    char *data = malloc(3);
                    strcpy(data, "{}");
                    service_invoke_reply(serviceId, rrpc_id, recv->data.sync_service_invoke.msg_id, data);
                }
            }            
        }

        cJSON_Delete(root);
        }
    if (recv->type == AIOT_DMRECV_ASYNC_SERVICE_INVOKE) { // 异步服务调用
        cJSON *root = cJSON_ParseWithLength(recv->data.async_service_invoke.params, recv->data.async_service_invoke.params_len);
        if (root == NULL) {
            printf("cJSON_Parse error\n");
            return;
        }
        if (strcmp(recv->data.async_service_invoke.service_id, "dev_upgrade") == 0) {
            cJSON *type = cJSON_GetObjectItem(root, "type");
            cJSON *firmware_url = cJSON_GetObjectItem(root, "firmware_url");
            cJSON *firmware_md5 = cJSON_GetObjectItem(root, "firmware_md5");
            cJSON *upgrade_now = cJSON_GetObjectItem(root, "upgrade_now");
            cJSON *version_current = cJSON_GetObjectItem(root, "version_current");
            if (type && firmware_url && firmware_md5 && upgrade_now && version_current) {
                software_update_arg.type = strdup(type->valuestring);
                software_update_arg.firmware_url = strdup(firmware_url->valuestring);
                software_update_arg.firmware_md5 = strdup(firmware_md5->valuestring);
                software_update_arg.upgrade_now = upgrade_now->valueint;
                software_update_arg.version_current = strdup(version_current->valuestring);
                Task task = {software_update, (void*)&software_update_arg};
                enqueue(&mb_task_queue, task);
            }
            } else if (strcmp(recv->data.async_service_invoke.service_id, "get_device_file") == 0) {
            cJSON *file_path = cJSON_GetObjectItem(root, "file_path");
            if (file_path) {
                GEMINAI_LOGI(TAG, "get_device_file: %s", file_path->valuestring);
                Task task = {geminai_upload_log, NULL}; //(void*)strdup(file_path->valuestring)};
                enqueue(&mb_task_queue, task);
            }
            
        }
        cJSON_Delete(root);
    }
    }

//不断读取队列中需要上传的信息
void mqtt_send_task(void *pvParameters)
{
    MqttMessage mqtt_msg;
    int32_t     res = STATE_SUCCESS;
    if(mqtt_queue==NULL)
    {
        mqtt_queue = xQueueCreate(MQTT_QUEUE_SIZE, sizeof(MqttMessage));
        if(mqtt_queue == NULL)
        {
            GEMINAI_LOGI(TAG,"create mqtt queue error %s",__FUNCTION__);
        }
        else
            GEMINAI_LOGI(TAG,"create mqtt queue success %s",__FUNCTION__);
    }
    while (1) {
        if (xQueueReceive(mqtt_queue, &mqtt_msg, portMAX_DELAY) == pdTRUE) {
            // 在这里执行 MQTT 发送操作，使用 mqtt_msg 中的消息内容和对应的 topic
            switch (mqtt_msg.topic) {
                case SHADOW:
                    mqtt_msg.shadowMessage->device_name = base_station.imei;
                    mqtt_msg.shadowMessage->product_key = base_station.product_key;
                    res = STATE_SUCCESS;
                    if(shadow_handler != NULL)
                        res = aiot_shadow_send(shadow_handler, mqtt_msg.shadowMessage);
                    else 
                        GEMINAI_LOGI(TAG, "shadow_handler is NULL!!!");

                    if(mqtt_msg.shadowMessage->type == AIOT_SHADOWMSG_UPDATE && mqtt_msg.shadowMessage->data.update.reported != NULL)
                    {
                        GEMINAI_LOGD(TAG, "shadow params = [%s]\n",mqtt_msg.shadowMessage->data.update.reported);  
                        free(mqtt_msg.shadowMessage->data.update.reported);
                    }                    
                    if(mqtt_msg.shadowMessage){
                        free(mqtt_msg.shadowMessage);
                        mqtt_msg.shadowMessage = NULL;
                    }
                    if(res < STATE_SUCCESS)
                        GEMINAI_LOGI(TAG, "aiot_shadow_send failed -0x%04lX\n", res);
                    // 发送到 影子模型
                    break;
                case PHYSICAL:
                    mqtt_msg.dmMessage->device_name = base_station.imei;
                    mqtt_msg.dmMessage->product_key = base_station.product_key;
                    if(dm_handler == NULL)                        
                        GEMINAI_LOGI(TAG, "dm_handler is NULL");
                    else if(mqtt_msg.dmMessage == NULL)                        
                        GEMINAI_LOGI(TAG, "mqtt_msg.dmMessage is NULL");
                    else
                        res = aiot_dm_send(dm_handler, mqtt_msg.dmMessage);

                    if(mqtt_msg.dmMessage->type == AIOT_DMMSG_PROPERTY_POST){
                        GEMINAI_LOGD(TAG, "params = [%s]\n",mqtt_msg.dmMessage->data.property_post.params);                        
                        free(mqtt_msg.dmMessage->data.property_post.params);
                    }
                    if(mqtt_msg.dmMessage->type == AIOT_DMMSG_EVENT_POST){
                        GEMINAI_LOGD(TAG, "id = [%s]\n",mqtt_msg.dmMessage->data.event_post.event_id);
                        GEMINAI_LOGD(TAG, "params = [%s]\n",mqtt_msg.dmMessage->data.event_post.params);
                        free(mqtt_msg.dmMessage->data.event_post.params);
                        free(mqtt_msg.dmMessage->data.event_post.event_id);
                        mqtt_msg.dmMessage->data.event_post.params = NULL;
                        mqtt_msg.dmMessage->data.event_post.event_id = NULL;
                    }          
                    if(mqtt_msg.dmMessage->type == AIOT_DMMSG_SYNC_SERVICE_REPLY){
                        GEMINAI_LOGD(TAG, "service_id = [%s]",mqtt_msg.dmMessage->data.sync_service_reply.service_id);
                        GEMINAI_LOGD(TAG, "rrpc_id = [%s]",mqtt_msg.dmMessage->data.sync_service_reply.rrpc_id);
                        GEMINAI_LOGD(TAG, "msg_id = [%lld]",mqtt_msg.dmMessage->data.sync_service_reply.msg_id);
                        GEMINAI_LOGD(TAG, "data = [%s]",mqtt_msg.dmMessage->data.sync_service_reply.data);
                        free(mqtt_msg.dmMessage->data.sync_service_reply.service_id);
                        free(mqtt_msg.dmMessage->data.sync_service_reply.rrpc_id);
                        free(mqtt_msg.dmMessage->data.sync_service_reply.data);
                    }          
                    if(mqtt_msg.dmMessage){
                        free(mqtt_msg.dmMessage);
                        mqtt_msg.dmMessage = NULL;
                    }
                    if(res < STATE_SUCCESS){
                        GEMINAI_LOGI(TAG, "aiot_dm_send failed -0x%04lX\n", res);
                    }
                    // 发送到 物理型
                    break;
                default:
                    break;
            }
        }
    }
}

//往主题中发送消息
void add_mqtt_message_to_queue(Topic topic, void* msg)
{
    MqttMessage mqtt_msg;
    switch(topic)
    {
        case SHADOW:
            mqtt_msg.shadowMessage = msg;
            // 发送到 影子模型
            break;
        case PHYSICAL:
            mqtt_msg.dmMessage = msg;
            // 发送到 物理型
            break;
        default:
            break;
    }
    mqtt_msg.topic = topic;

    if(mqtt_queue==NULL)
    {
        mqtt_queue = xQueueCreate(MQTT_QUEUE_SIZE, sizeof(MqttMessage));
        if(mqtt_queue == NULL)
        {
            GEMINAI_LOGI(TAG, "%s create mqtt queue error ", __FUNCTION__);
            goto FAILCREATEQUERE;
        }
        else
            GEMINAI_LOGI(TAG, "%s create mqtt queue success ", __FUNCTION__);
    
    }    

    if (xQueueSendToBack(mqtt_queue, &mqtt_msg, 0) != pdPASS) {
        GEMINAI_LOGI(TAG, "MQTT queue is full. Message not added to queue.");
FAILCREATEQUERE:        
        switch(topic)
        {
            case SHADOW:
                if(mqtt_msg.shadowMessage->type == AIOT_SHADOWMSG_UPDATE && mqtt_msg.shadowMessage->data.update.reported != NULL)
                {
                    free(mqtt_msg.shadowMessage->data.update.reported);
                }
                if(mqtt_msg.shadowMessage){
                    free(mqtt_msg.shadowMessage);
                    mqtt_msg.shadowMessage = NULL;
                }
                break;
            case PHYSICAL:
                if(mqtt_msg.dmMessage->type == AIOT_DMMSG_PROPERTY_POST && mqtt_msg.dmMessage->data.property_post.params != NULL)
                {
                    free(mqtt_msg.dmMessage->data.property_post.params);
                    mqtt_msg.dmMessage->data.property_post.params = NULL;
                }
                else if (mqtt_msg.dmMessage->type == AIOT_DMMSG_EVENT_POST )
                {
                    if(mqtt_msg.dmMessage->data.event_post.params != NULL)
                    {
                        free(mqtt_msg.dmMessage->data.event_post.params);
                        mqtt_msg.dmMessage->data.event_post.params = NULL;                        
                    }
                    if(mqtt_msg.dmMessage->data.event_post.event_id != NULL)
                    {
                        free(mqtt_msg.dmMessage->data.event_post.event_id);
                        mqtt_msg.dmMessage->data.event_post.event_id = NULL;                        
                    }                    
                }
                if(mqtt_msg.dmMessage){
                    free(mqtt_msg.dmMessage);
                    mqtt_msg.dmMessage = NULL;
                }                
                break;
            default:
                break;
        }        
    }
}
TaskHandle_t attributeSendTask = NULL;
//初始化接收与发送mqtt消息
void mqtt_quere_init(void)
{
    GEMINAI_LOGI(TAG, "mqtt_quere_init");
    /*影子模型*/   /*需添加初始化失败异常处理*/
    shadow_handler = aiot_shadow_init();
    if(shadow_handler == NULL)
    {
        printf("aiot_shadow_init failed\n");
    }
    aiot_shadow_setopt(shadow_handler, AIOT_SHADOWOPT_MQTT_HANDLE, mqtt_handle);
    aiot_shadow_setopt(shadow_handler, AIOT_SHADOWOPT_RECV_HANDLER, (void *)demo_shadow_recv_handler);

    // demo_get_shadow(shadow_handler);

    /*物理型*/    /*需添加初始化失败异常处理*/
    dm_handler = aiot_dm_init();
    if(dm_handler == NULL)
    {
        printf("aiot_dm_init failed\n");
    }    
    aiot_dm_setopt(dm_handler, AIOT_DMOPT_MQTT_HANDLE, mqtt_handle);
    aiot_dm_setopt(dm_handler, AIOT_DMOPT_RECV_HANDLER, (void *)yqsl_np_dm_recv_handler);

    xTaskCreate(mqtt_send_task, "MqttSendTask", 4096, NULL, 5, NULL);
}

void attribute_send_task_start(void)
{
    xTaskCreate(attribute_send_task, "AttributeSendTask", 4*1024, NULL, 5, &attributeSendTask);
}

void attribute_send_task_stop(void)
{
    if(attributeSendTask != NULL)
    {
        vTaskDelete(attributeSendTask);
        attributeSendTask = NULL;
    }
}

//添加物理型事件发送
void aliyun_send_event_mqtt(aiot_iat_event_enum event, void *para)
{
	char *id = (char*)malloc(48);
	if (id == NULL) {
        GEMINAI_LOGW(TAG,"%s Failed to create char object", __FUNCTION__);
        if(para != NULL)
        {
            free(para);
            para = NULL;
        }
        return ;
    }
	memset(id, 0, 48);
    aiot_dm_msg_t *dm_msg;
    dm_msg = (aiot_dm_msg_t*)malloc(sizeof(aiot_dm_msg_t));
	if (dm_msg == NULL) {
        GEMINAI_LOGW(TAG,"%s Failed to create aiot_dm_msg_t object", __FUNCTION__);
        if(para != NULL)
        {
            free(para);
            para = NULL;
        }
        if(id != NULL)
        {
            free(id);
            id = NULL;
        }        
        return ;
    }    
    memset(dm_msg, 0, sizeof(aiot_dm_msg_t));

    dm_msg->type = AIOT_DMMSG_EVENT_POST;
    switch(event)
    {
        case AIOT_IAT_EVENT_COOR_SALES:
            strcpy(id, "sale_event_cloud_coordination");
            break;
        case AIOT_IAT_EVENT_DISPLAY_V2:
            strcpy(id, "display_event_v2");
            break;
        case AIOT_IAT_EVENT_BOOTUP:
            strcpy(id, "boot_event");
            break;  
        case AIOT_IAT_EVENT_CHECK_EVENT:
            strcpy(id, "check_event");
            break;
        case AIOT_IAT_EVENT_WARNING:
            strcpy(id, "warning_event");
            break;
        case AIOT_IAT_EVENT_LOCATION:
            strcpy(id, "shutdown_base_station_event");
            break;
        default:
            GEMINAI_LOGI(TAG,"unknow event :[%d]", event);
            break;
    }
    dm_msg->data.event_post.event_id = id;
    dm_msg->data.event_post.params = para;
    add_mqtt_message_to_queue(PHYSICAL, dm_msg);
    return ;
}

//开机事件发送
void boot_event_send(void)
{
    cJSON *root = cJSON_CreateObject();
    char *json_string = NULL;
    if (root == NULL) {
        GEMINAI_LOGI(TAG, "Failed to create JSON object");
        return ;
    }
    time_t now;    
    // 获取当前系统时间
    time(&now);
    char i=0;
    while(1)
    {
        i++;
        if(now < 946656000)
        {
            vTaskDelay(pdMS_TO_TICKS(2000));
            GEMINAI_LOGI(TAG, "time:[%lld]", now);
            time(&now);
            if(i>3){
                break;
            }
        }
        else{
            break;
        }
    }    
    char buffer[24]={0}; // 假设足够存储转换后的字符串

    // 使用 snprintf 将整数转换为字符串
    snprintf(buffer, sizeof(buffer), "%lld", now*1000);

    cJSON_AddStringToObject(root, "asset_id", base_station.asset_id);
    cJSON_AddStringToObject(root, "event_time", buffer);
    json_string = cJSON_PrintUnformatted (root);
    aliyun_send_event_mqtt(AIOT_IAT_EVENT_BOOTUP, json_string);
    cJSON_Delete(root);
    GEMINAI_LOGI(TAG, "boot_event_send:[%lld]", now);
    return ;
}

//视觉模块事件上报
int vision_event_report(char *event, void *para)
{
    if(event == NULL)
    {
        if(para!=NULL)
            free(para);
        return -1;
    }
	char *id = (char*)malloc(strlen(event)+1);
    if(id == NULL){
        GEMINAI_LOGI(TAG,"Failed to create char object");
        return -1;
    }
	memset(id, 0, strlen(event)+1);
    strncpy(id, event,strlen(event) );

    aiot_dm_msg_t *dm_msg;

    dm_msg = (aiot_dm_msg_t*)malloc(sizeof(aiot_dm_msg_t));
	if (dm_msg == NULL) {
        GEMINAI_LOGI(TAG,"Failed to create aiot_dm_msg_t object");
        if(id != NULL)
        {
            free(id);
            id = NULL;
        }        
        return -1;
    }
    memset(dm_msg, 0, sizeof(aiot_dm_msg_t));

    dm_msg->type = AIOT_DMMSG_EVENT_POST;
    dm_msg->data.event_post.event_id = id;
    dm_msg->data.event_post.params = para;
    add_mqtt_message_to_queue(PHYSICAL, dm_msg);
    return 0;        
}

//服务调用回复
void service_invoke_reply(char *service_id, char *rrpc_id, uint64_t msg_id, char *data)
{
    aiot_dm_msg_t *dm_msg;
    dm_msg = (aiot_dm_msg_t*)malloc(sizeof(aiot_dm_msg_t));
    if (dm_msg == NULL) {
        GEMINAI_LOGI(TAG, "Failed to malloc dm_msg");
        return ;
    }
    dm_msg->type = AIOT_DMMSG_SYNC_SERVICE_REPLY;
    dm_msg->data.sync_service_reply.service_id = service_id;
    dm_msg->data.sync_service_reply.rrpc_id = rrpc_id;
    dm_msg->data.sync_service_reply.msg_id = msg_id;
    dm_msg->data.sync_service_reply.code = 200;
    dm_msg->data.sync_service_reply.data = data;
    add_mqtt_message_to_queue(PHYSICAL, dm_msg);       
}

//属性上报
inline void attribute_report(char* json_string)
{
    aiot_dm_msg_t *dm_msg;
    dm_msg = (aiot_dm_msg_t*)malloc(sizeof(aiot_dm_msg_t));
    dm_msg->type = AIOT_DMMSG_PROPERTY_POST;
    if (dm_msg == NULL) {
        GEMINAI_LOGI(TAG, "Failed to malloc dm_msg");
        free(json_string);
        return ;
    }
    dm_msg->data.property_post.params = json_string;
    add_mqtt_message_to_queue(PHYSICAL, dm_msg);    
    
}

//循环检查是否有属性需要发送
void attribute_send_task(void *arg)
{
    cJSON *root;    
    char *json_string = NULL;
    static time_t last, now;
    vTaskDelay(60000 / portTICK_PERIOD_MS);
    while(1)
    {  
        // 获取当前系统时间
        time(&now);
        if((llabs(now-last) > system_para.report_interval ))
        {
            regularly_report_task(NULL);
            time(&last);
        }

        vTaskDelay(500 / portTICK_PERIOD_MS);
        
        //影子模型
        if(attribute_send_event & PARA_SHADOW)
        {
            //定时上报任务
            if(report_interval != system_para.report_interval && report_interval != 0)
            {
                system_para.report_interval = report_interval;
            }
            send_shadow_update_event();
            attribute_send_event &=~ PARA_SHADOW;
            continue;
        }
        if(attribute_send_event != 0)
        {
        //属性发送
        root = cJSON_CreateObject();
        
        if (root == NULL) {
            GEMINAI_LOGI(TAG, "Failed to create JSON object");
            continue ;
        }
   

        if(attribute_send_event & PARA_SET_TEMP_DIFF)       {cJSON_AddNumberToObject(root, "temperature_difference", temp_ctl_para.temp_diff);  attribute_send_event &=~ PARA_SET_TEMP_DIFF;}
        if(attribute_send_event & PARA_SET_TEMP_DES)        {cJSON_AddNumberToObject(root, "temperature_target", temp_ctl_para.temp_des);       attribute_send_event &=~ PARA_SET_TEMP_DES;}
        if(attribute_send_event & PARA_SET_DELAY_TIM)       {cJSON_AddNumberToObject(root, "compressor_min_downtime", temp_ctl_para.delay_tim); attribute_send_event &=~ PARA_SET_DELAY_TIM;}
        if(attribute_send_event & PARA_COOL_SWITCH)         {cJSON_AddNumberToObject(root, "colding_switch_status", frig_sys_switch); 
                                                             cJSON_AddNumberToObject(root, "evaporator_status", frig_sys_switch); 
                                                             cJSON_AddNumberToObject(root, "compressor_status", frig_sys_switch);attribute_send_event &=~ PARA_COOL_SWITCH;}
        if(attribute_send_event & PARA_LIGHT_SWITCH)        {cJSON_AddNumberToObject(root, "light_switch_status", led_status);     attribute_send_event &=~ PARA_LIGHT_SWITCH;}
        if(attribute_send_event & PARA_LED_PWM)             {cJSON_AddNumberToObject(root, "logo_light_brightness", temp_ctl_para.led_pwm);        attribute_send_event &=~ PARA_LED_PWM;}
        if(attribute_send_event & PARA_EVAPORATOR_STATUS)   {cJSON_AddNumberToObject(root, "evaporator_status", RLY_FANS_GET);       attribute_send_event &=~ PARA_EVAPORATOR_STATUS;}
        if(attribute_send_event & PARA_COMPRESSOR_STATUS)   {cJSON_AddNumberToObject(root, "compressor_status", RLY_COMP_GET);       attribute_send_event &=~ PARA_COMPRESSOR_STATUS;}
        if(attribute_send_event & PARA_COLD_NORMAL_STATE)   {cJSON_AddNumberToObject(root, "kn_fridge_config:colding_status", 2);          attribute_send_event &=~ PARA_COLD_NORMAL_STATE;}
        if(attribute_send_event & PARA_COLD_DEFROST_STATE)  {cJSON_AddNumberToObject(root, "kn_fridge_config:colding_status", 3);          attribute_send_event &=~ PARA_COLD_DEFROST_STATE;}
        if(attribute_send_event & PARA_COLD_FROCE_STATE)    {cJSON_AddNumberToObject(root, "kn_fridge_config:colding_status", 4);          attribute_send_event &=~ PARA_COLD_FROCE_STATE;}
        if(attribute_send_event & PARA_VOLUME)              {cJSON_AddNumberToObject(root, "volume", 100);                  attribute_send_event &=~ PARA_VOLUME;}     

        json_string = cJSON_PrintUnformatted (root);
        attribute_report(json_string);
        cJSON_Delete(root);
        }

        if(attribute_send_event & PARA_OVERTEMP_ALARM)
        {
            vTaskDelay(500 / portTICK_PERIOD_MS);
            attribute_send_event &=~ PARA_OVERTEMP_ALARM;
            if(temp_ctl_para.overtemp_flag)
                warning_event_send(WARNING_CODE_OVERTEMP_ALARM, 1);
            else
                warning_event_send(WARNING_CODE_OVERTEMP_ALARM, 0);
        }
        if(attribute_send_event & PARA_LOWTEMP_ALARM)
        {
            vTaskDelay(500 / portTICK_PERIOD_MS);
            attribute_send_event &=~ PARA_LOWTEMP_ALARM;
            if(temp_ctl_para.lowtemp_flag)
                warning_event_send(WARNING_CODE_LOWTEMP_ALARM, 1);
            else
                warning_event_send(WARNING_CODE_LOWTEMP_ALARM, 0);
        }
    }
    return ;
}

//组装告警事件内容
char* generate_waring_content(const char* basic_error_info, const char* extra_error_info)
{
    char* result = malloc(strlen(basic_error_info) + strlen(extra_error_info) + 54);
    memset(result, 0 , strlen(basic_error_info) + strlen(extra_error_info) + 54);
    sprintf(result, "{\\\"basic_error_info\\\":\\\"%s\\\",\\\"extra_error_info\\\":\\\"%s\\\"}",basic_error_info, extra_error_info);
    return result;
}

//告警事件发送
void warning_event_send(aiot_warning_code_enum code, int state)
{
    cJSON *root = cJSON_CreateObject();
    char *json_string = NULL;
    if (root == NULL) {
        GEMINAI_LOGI(TAG, "Failed to create JSON object");
        return ;
    }
    time_t now;    
    // 获取当前系统时间
    time(&now); 
    char buffer[24]={0}; // 假设足够存储转换后的字符串

    // 使用 snprintf 将整数转换为字符串
    snprintf(buffer, sizeof(buffer), "%lld", now*1000);

    cJSON_AddStringToObject(root, "asset_id", base_station.asset_id);
    cJSON_AddStringToObject(root, "event_time", buffer);
    cJSON_AddNumberToObject(root, "error_code", code);
    cJSON_AddNumberToObject(root, "is_abnormal", state);

    switch (code)
    {
    case WARNING_CODE_OVERTEMP_ALARM:
        if(state)
            cJSON_AddStringToObject(root, "content", generate_waring_content("overtemp_warning", "index:1"));
        else
            cJSON_AddStringToObject(root, "content", generate_waring_content("release_overtemp_warning", "index:1"));
        break;
    case WARNING_CODE_LOWTEMP_ALARM:
        if(state)
            cJSON_AddStringToObject(root, "content", generate_waring_content("lowtemp_warning", "index:1"));
        else
            cJSON_AddStringToObject(root, "content", generate_waring_content("release_lowtemp_warning", "index:1"));
        break;      
    
    default:
        break;
    }


    json_string = cJSON_PrintUnformatted (root);
    aliyun_send_event_mqtt(AIOT_IAT_EVENT_WARNING, json_string);
    cJSON_Delete(root);
    return ;
}

//定时上报消息
void regularly_report_task(void* arg)
{

    char *json_string = NULL;
    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        printf("Failed to create JSON object\n");
        return ;
    }
    cJSON *work_time = cJSON_CreateObject();
    if (work_time == NULL) {
        printf("Failed to create JSON object\n");
        cJSON_Delete(root);
        return ;
    }
    cJSON *work_count = cJSON_CreateObject();
    if (work_count == NULL) {
        printf("Failed to create JSON object\n");
        cJSON_Delete(root);
        cJSON_Delete(work_time);
        return ;
    }
    cJSON *power_info = cJSON_CreateObject();
    if (power_info == NULL) {
        printf("Failed to create JSON object\n");
        cJSON_Delete(root);
        cJSON_Delete(work_time);
        cJSON_Delete(work_count);
        return ;
    }    
    
    time_t now;    
    // 获取当前系统时间
    time(&now);
    char buffer[24]={0}; // 假设足够存储转换后的字符串

    // 使用 snprintf 将整数转换为字符串
    snprintf(buffer, sizeof(buffer), "%lld", now*1000);    

    //工作次数
    cJSON_AddNumberToObject(work_count, "condenser_relay_times", devices_tim_cnt.c_vaporizerrelay);
    cJSON_AddNumberToObject(work_count, "evaporator_relay_times", devices_tim_cnt.c_vaporizerrelay);
    cJSON_AddNumberToObject(work_count, "compressor_relay_times", devices_tim_cnt.c_compressorrelay);
    cJSON_AddNumberToObject(work_count, "compressor_times", devices_tim_cnt.c_compressorrelay);
    cJSON_AddNumberToObject(work_count, "condenser_times", devices_tim_cnt.c_vaporizerrelay);
    cJSON_AddNumberToObject(work_count, "evaporator_times", devices_tim_cnt.c_vaporizerrelay);
    cJSON_AddStringToObject(work_count, "asset_id", base_station.asset_id);
    cJSON_AddStringToObject(work_count, "event_time", buffer);
    
    cJSON_AddItemToObject(root, "working_count", work_count);

    //工作时长
    cJSON_AddNumberToObject(work_time, "cpu", 0);
    cJSON_AddNumberToObject(work_time, "mcu", 0);
    cJSON_AddNumberToObject(work_time, "compressor", devices_tim_cnt.t_compressor);
    cJSON_AddNumberToObject(work_time, "condenser_fan", devices_tim_cnt.t_vaporizerfan);
    cJSON_AddNumberToObject(work_time, "evaporator_fan", devices_tim_cnt.t_vaporizerfan);
    cJSON_AddNumberToObject(work_time, "logo_light", devices_tim_cnt.t_logo);
    cJSON_AddNumberToObject(work_time, "atmosphere_light", devices_tim_cnt.t_env_light);
    cJSON_AddStringToObject(work_time, "asset_id", base_station.asset_id);
    cJSON_AddStringToObject(work_time, "event_time", buffer);
    
    cJSON_AddItemToObject(root, "working_time", work_time);

    //功率计
    Meter_Recv_once();
    cJSON_AddNumberToObject(power_info, "voltage", runingInf.voltage);
    cJSON_AddNumberToObject(power_info, "current", runingInf.electricity);
    cJSON_AddNumberToObject(power_info, "power", runingInf.power);
    cJSON_AddNumberToObject(power_info, "power_consumption", runingInf.power_energy);
    cJSON_AddStringToObject(power_info, "asset_id", base_station.asset_id);
    cJSON_AddStringToObject(power_info, "event_time", buffer);

    cJSON_AddItemToObject(root, "power_info", power_info);

    //温度
    cJSON_AddNumberToObject(root, "temperature", sys_temp.real_temp);
    cJSON_AddNumberToObject(root, "temperature_environment", sys_temp.around_temp);

    //压缩机、风机  
    cJSON_AddNumberToObject(root, "compressor_status", RLY_COMP_GET);
    cJSON_AddNumberToObject(root, "evaporator_status", RLY_FANS_GET);   

    //电池
    cJSON_AddNumberToObject(root, "battery", calculate_remaining_capacity());
    
    //除霜累计时长
    cJSON_AddNumberToObject(root, "kn_fridge_config:defrost_exec_time", dafrost_exec_get());

    /*处于ppp模式下无法发送at查询，以下不查*/
    //网络信号强度
    //信号质量
    //定位信息
    
    /*1106状态*/
    //系统监控数据
    
    json_string = cJSON_PrintUnformatted (root);
    printf("***********\n");
    printf("%s\n", json_string);
    printf("***********\n");
    attribute_report(json_string);
    cJSON_Delete(root);

}

//掉电定位事件发送
void send_shutdown_base_station_event(void)
{
    cJSON *root = cJSON_CreateObject();
    char *json_string = NULL;
    if (root == NULL) {
        GEMINAI_LOGI(TAG, "%s Failed to create JSON object", __FUNCTION__);
        return ;
    }
    time_t now;    
    // 获取当前系统时间
    time(&now);
    char i=0;
    while(1)
    {
        i++;
        if(now < 946656000)//2000.1.1
        {
            vTaskDelay(pdMS_TO_TICKS(2000));
            GEMINAI_LOGI(TAG, "%s time:[%lld]", __FUNCTION__, now);
            time(&now);
            if(i>3){
                break;
            }
        }
        else{
            break;
        }
    }    
    char buffer[24]={0}; // 假设足够存储转换后的字符串
    char baseStaion[256]={0};
    i=0;
    while(1)
    {
        i++;
        if(base_station.cid[0] == '\0')
        {
            vTaskDelay(pdMS_TO_TICKS(2000));
            GEMINAI_LOGI(TAG, "cid is NULL");
            if(i>3){
                break;
            }
        }
        else{
            break;
        }
    }    
    snprintf(buffer, sizeof(buffer), "%lld", now*1000);
    // 使用 snprintf 将整数转换为字符串.
    //                                 cid:220575300#lac:0x2490#mcc:460#mnc:00#networktype:537#ss:37#ta:1
    snprintf(baseStaion, sizeof(baseStaion), "cid:%s#lac:0x%s#mcc:%s#mnc:%s#networktype:%s#ss:%d#ta:1", base_station.cid, base_station.lac, base_station.mcc, base_station.mnc, base_station.net,  base_station.ss);

    cJSON_AddStringToObject(root, "asset_id", base_station.asset_id);
    cJSON_AddStringToObject(root, "event_time", buffer);
    cJSON_AddNumberToObject(root, "mcu_battery", calculate_remaining_capacity());
    cJSON_AddStringToObject(root, "base_station", baseStaion);
    cJSON_AddStringToObject(root, "near_station", "");

    json_string = cJSON_PrintUnformatted (root);
    aliyun_send_event_mqtt(AIOT_IAT_EVENT_LOCATION, json_string);
    cJSON_Delete(root);
    GEMINAI_LOGI(TAG, "%s hutdown_base_station_event:[%lld]", __FUNCTION__, now);
    return ;
}

//发送影子模型
void send_shadow_update_event(void)
{
    cJSON *root = cJSON_CreateObject();
    cJSON *display = cJSON_CreateObject();
    cJSON *door = cJSON_CreateObject();
    cJSON *frig = cJSON_CreateObject();
    cJSON *lock = cJSON_CreateObject();
    cJSON *sale = cJSON_CreateObject();
    cJSON *smart_diag = cJSON_CreateObject();
    cJSON *system = cJSON_CreateObject();

    cJSON_AddNumberToObject(display, "correction", 1);
    cJSON_AddNumberToObject(display, "origin_image_upload", 0);

    cJSON_AddNumberToObject(door, "origin_image_upload", 1);
    cJSON_AddNumberToObject(door, "door_role", 1);

    cJSON_AddNumberToObject(frig, "defrost_cycle", temp_ctl_para.defrost_cycle);
    cJSON_AddNumberToObject(frig, "defrost_shielding_time", temp_ctl_para.defrost_shielding_time);
    cJSON_AddNumberToObject(frig, "defrost_time", temp_ctl_para.defrost_time);
    cJSON_AddNumberToObject(frig, "lowtemp_alert", temp_ctl_para.lowtemp);
    cJSON_AddNumberToObject(frig, "overtemp_alarm_delay_time", temp_ctl_para.overtemp_alarm_delay_time);
    cJSON_AddNumberToObject(frig, "overtemp_alert", temp_ctl_para.overtemp);
    cJSON_AddNumberToObject(frig, "start_shielding_time", temp_ctl_para.start_shielding_time);

    cJSON_AddNumberToObject(lock, "device_lock", temp_ctl_para.device_lock);

    cJSON_AddNumberToObject(sale, "is_pack", 1);
    cJSON_AddNumberToObject(sale, "max_frames", 900);
    cJSON_AddNumberToObject(sale, "pick_upload", 1);

    cJSON_AddNumberToObject(smart_diag, "enable", 1);

    cJSON_AddNumberToObject(system, "report_interval", system_para.report_interval);
    cJSON_AddNumberToObject(system, "volume", system_para.volume);

    cJSON_AddItemToObject(root, "display", display);
    cJSON_AddItemToObject(root, "door", door);
    cJSON_AddItemToObject(root, "frig", frig);
    cJSON_AddItemToObject(root, "lock", lock);
    cJSON_AddItemToObject(root, "sale", sale);
    cJSON_AddItemToObject(root, "smart_diag", smart_diag);
    cJSON_AddItemToObject(root, "system", system);

    aiot_shadow_msg_t *sd_msg;
    sd_msg = (aiot_shadow_msg_t*)malloc(sizeof(aiot_shadow_msg_t));
	if (sd_msg == NULL) {
        GEMINAI_LOGI(TAG,"Failed to create aiot_shadow_msg_t object");
        return ;
    }    
    memset(sd_msg, 0, sizeof(aiot_shadow_msg_t));

    char *json_string;
    json_string = cJSON_Print(root);
    
    sd_msg->type = AIOT_SHADOWMSG_UPDATE;
    sd_msg->data.update.reported = json_string;
    sd_msg->data.update.version = shadow_version + 1;

    add_mqtt_message_to_queue(SHADOW, sd_msg);
}

//发送定位信息
void send_location_info(void)
{
    cJSON *base_station_root = cJSON_CreateObject();
    if (base_station_root == NULL) {
        GEMINAI_LOGI(TAG, "%s Failed to create JSON object", __FUNCTION__);
        return ;
    }
    cJSON *near_station_root = cJSON_CreateObject();
    if (near_station_root == NULL) {
        GEMINAI_LOGI(TAG, "%s Failed to create JSON object", __FUNCTION__);
        return ;
    }

    /*{
    "base_station": "cid:213707141#lac:0x2482#mcc:460#mnc:00#net:5#ss:57#ta:1",
    "near_station": "",
    "asset_id": "1545024023493",
    "event_time": "1501914051165"
    }*/
    time_t now;    
    // 获取当前系统时间
    time(&now);
    char i=0;
    while(1)
    {
        i++;
        if(now < 946656000)
        {
            vTaskDelay(pdMS_TO_TICKS(2000));
            GEMINAI_LOGI(TAG, "time:[%lld]", now);
            time(&now);
            if(i>3){
                break;
            }
        }
        else{
            break;
        }
    }    
    char *buffer = malloc(256); 
    memset(buffer, 0, 256);

    // 使用 snprintf 将整数转换为字符串
    snprintf(buffer, 256, "%lld", now*1000);


    cJSON_AddStringToObject(base_station_root, "event_time", buffer);
    memset(buffer, 0, 256);
    snprintf(buffer, 256, "cid:%s#lac:0x%s#mcc:%s#mnc:%s#net:%s#ss:%d#ta:1", base_station.cid, base_station.lac, base_station.mcc, base_station.mnc, base_station.net,  base_station.ss);
    cJSON_AddStringToObject(base_station_root, "base_station", buffer);
    cJSON_AddStringToObject(base_station_root, "near_station", "");
    cJSON_AddStringToObject(base_station_root, "asset_id", base_station.asset_id);

    free(buffer);
    // cJSON_AddStringToObject(root, "near_station", "");

    cJSON *root = cJSON_CreateObject();
    if (root == NULL) {
        GEMINAI_LOGI(TAG, "%s Failed to create root JSON object", __FUNCTION__);
        return ;
    }
    cJSON_AddItemToObject(root, "base_station_info", base_station_root);
    char *base_station_json_string ;

    base_station_json_string = cJSON_PrintUnformatted (root);
    cJSON_Delete(root);
    attribute_report(base_station_json_string); 
    printf("***********\n");
    printf("%s\n", base_station_json_string);
    printf("***********\n");
    
}
